'use strict';

var utils = require('./../utils');

function InterceptorManager() {
  this.handlers = [];
}

/**
 * 在栈中添加一个新的拦截器
 *
 * @param {Function} fulfilled 处理`Promise`的`then`的函数
 * @param {Function} rejected 处理`Promise`的`reject`的函数
 * @param {Object} options 配置同步、是否拦截，但是只针对请求前拦截
 * @return {Number} 一个用于以后删除拦截器的ID
 */
InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {
  this.handlers.push({
    fulfilled: fulfilled,
    rejected: rejected,
    // 同步处理拦截，默认是true，如果是false的话那么，处理config的过程也算在异步Promise内
    synchronous: options ? options.synchronous : false,
    // 在什么条件下允许，是一个函数参数是最终的config，但会false就不执行该拦截器
    runWhen: options ? options.runWhen : null,
  });
  // 返回该拦截器的索引当作ID
  return this.handlers.length - 1;
};

/**
 * 根据ID在栈中移除一个拦截器
 *
 * @param {Number} id `use`方法返回的拦截器ID
 */
InterceptorManager.prototype.eject = function eject(id) {
  if (this.handlers[id]) {
    this.handlers[id] = null;
  }
};

/**
 * 迭代所有注册的拦截器
 *
 * 这个方法自动跳过`eject`移除为`null`的拦截器
 *
 * @param {Function} fn 为每个拦截器调用的函数
 */
InterceptorManager.prototype.forEach = function forEach(fn) {
  utils.forEach(this.handlers, function forEachHandler(h) {
    if (h !== null) {
      fn(h);
    }
  });
};

module.exports = InterceptorManager;
